package uk.org.kano.wifilogin;

import java.net.MalformedURLException;
import java.net.URL;

import uk.org.kano.wifilogin.data.APAdapter;
import uk.org.kano.wifilogin.data.APXMLHandler;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class WifiLogin extends Activity implements View.OnClickListener
{
	// The accesspoint adapter
	private APAdapter ap_adap = null;
	
	// The downloader dialog
	private ProgressDialog pdDL = null;
	
	// The handler to notify on download complete
	private final Handler mHandler = new Handler();
	
	// The downloader thread
	private Thread dl_thread = null;

	// static errors
	private static final int ERR_NONE = 0;
	private static final int ERR_UNKNOWN = -1;
	private static final int ERR_CANCELLED = -2;
	private static final int ERR_BADURL = -3;
	// Error handling
	private int dl_code = ERR_NONE;
	private String dl_msg = null;
	private Object dl_lock = new Object();
	
	// safely get and set the error messages
	private void setDlError(int code, String message)
	{
		synchronized (dl_lock) {
			dl_code = code;
			dl_msg = message;
		}
	}
	private int getDlCode()
	{
		synchronized (dl_lock) {
			return dl_code;
		}
	}
	private String getDlMessage()
	{
		synchronized (dl_lock) {
			return new String(dl_msg);
		}
	}
	
	// What to do when the download is complete
    final Runnable mUpdateResults = new Runnable() {
    	public void run() {
    		finishDownload();
        }
    };
	
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        Button b;
        
        // run
        setContentView(R.layout.main);
        
        // register listeners
        b = (Button)findViewById(R.id.login_button);
        b.setOnClickListener(this);
        b = (Button)findViewById(R.id.view_accounts);
        b.setOnClickListener(this);
        b = (Button)findViewById(R.id.view_aps);
        b.setOnClickListener(this);
        
        // Load the accesspoints
        ap_adap = new APAdapter(this);
        
        if (0 == ap_adap.getCount()) {
        	// no aps present, prompt for download
        	new AlertDialog.Builder(this)
        		.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
        			public void onClick(DialogInterface dialog, int which) {
        				dialog.cancel();
        				showDownloadLoc();
        			}
        		})
        		.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
        			public void onClick(DialogInterface dialog, int which) {
        				dialog.cancel();
        			}
        		})
        		.setMessage(R.string.aps_download)
        		.setCancelable(false)
        		.setTitle(R.string.aps_download_header)
        		.create()
        		.show();
        }
    }
    
    /**
     * Show the download location for getting the accesspoints
     */
    private void showDownloadLoc()
    {
    	final EditText input = new EditText(this);    	
    	input.setText(R.string.aps_dl_loc);

    	new AlertDialog.Builder(this)
    	.setView(input)
		.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				dialog.cancel();
				startDownload(input.getText());
			}
		})
		.setCancelable(true)
		.setTitle(R.string.aps_dl_loc_header)
		.create()
		.show();
    }
    
    /**
     * Perform the download
     */
    private void startDownload(final CharSequence location)
    {
    	pdDL = ProgressDialog.show(this, "", getString(R.string.aps_dl_msg), true, true, new DialogInterface.OnCancelListener() {
			public void onCancel(DialogInterface dialog) {
				dl_thread.interrupt();
				// dl_thread.join();
			}
    	});
    	
    	// start a new thread to handle the download
    	dl_thread = new Thread() {
            public void run() {
            	APXMLHandler ah = null;
				try {
					ah = new APXMLHandler();
					ah.parseConfig(new URL(location.toString()));
				} catch (APXMLHandler.APXMLHandlerException e) {
					setDlError(ERR_UNKNOWN, e.getCause().getLocalizedMessage());
					Log.e(getString(R.string.app_name), e.toString());
				} catch (MalformedURLException e) {
					setDlError(ERR_BADURL, null);
					Log.e(getString(R.string.app_name), e.toString());
				} catch (InterruptedException e) {
					setDlError(ERR_CANCELLED, null);
					Log.e(getString(R.string.app_name), e.toString());
				}
            	// Only update the variables if we were not interrupted
				// Run things on the GUI thread
                mHandler.post(mUpdateResults);
            }
        };
        dl_thread.start();
    }
    
    /**
     * Complete the download and reset the main list (called on GUI thread)
     */
    private synchronized void finishDownload()
    {
    	int code;
    	if (null != pdDL)
    		pdDL.cancel();
    	pdDL = null;
    	
    	// display any errors or reload objects
    	code = getDlCode();
    	switch (code) {
    		case ERR_CANCELLED: Toast.makeText(this, R.string.aps_dl_cancelled, Toast.LENGTH_SHORT); break;
    		case ERR_BADURL: Toast.makeText(this, R.string.aps_dl_badurl, Toast.LENGTH_SHORT); break;
    		case ERR_UNKNOWN: Toast.makeText(this, getDlMessage(), Toast.LENGTH_SHORT); break;
    	}
       	// Now reload
    }
    
    /**
     * Button click listener
     * @param v The view
     */
    public void onClick(View v)
    {
    	if (v.getId() == R.id.view_accounts) {
    		Intent i = new Intent(this, AccountsActivity.class);
    		this.startActivityForResult(i, 0);
    	} else if (v.getId() == R.id.view_aps) {
    		Intent i = new Intent(this, ApsActivity.class);
    		this.startActivityForResult(i, 0);
    	} else if (v.getId() == R.id.login_button) {
    	}
    }
    
    /**
     * Catch sub-activities closing
     */
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
    	super.onActivityResult(requestCode, resultCode, data);
    	Log.d(this.toString(), "Caught activity close");
    }
}